import { useEffect, useState, type MutableRefObject } from 'react'
import { NavBar, Form, Input, TextArea, Button, Picker, DatePicker, Toast, ImageUploader, type ImageUploadItem } from 'antd-mobile'
import { useNavigate } from 'react-router-dom'
import request from '../../api/request'
import PermissionGuard from '../../components/PermissionGuard'
import { PERMISSION_OPERATIONS } from '../../utils/permission'
import './index.css'

interface DepartmentOption { label: string; value: number }
interface DiseaseOption { label: string; value: string }
interface RawDepartment { id: number; departmentName: string }
interface RawDisease { name: string }

const formatDate = (v?: Date) => {
  if (!v) return ''
  const y = v.getFullYear()
  const m = String(v.getMonth() + 1).padStart(2, '0')
  const d = String(v.getDate()).padStart(2, '0')
  return `${y}-${m}-${d}`
}

export default function SickCirclePublish() {
  const navigate = useNavigate()
  const [form] = Form.useForm()
  const [deptOptions, setDeptOptions] = useState<DepartmentOption[]>([])
  const [diseaseOptions, setDiseaseOptions] = useState<DiseaseOption[]>([])
  const [loading, setLoading] = useState(false)
  const [uploading, setUploading] = useState(false)
  const [images, setImages] = useState<ImageUploadItem[]>([])
  const [fileMap, setFileMap] = useState<Record<string, File>>({})

  const openPicker = (ref: MutableRefObject<{ open?: () => void } | null>) => {
    ref.current?.open?.()
  }

  // 将图片压缩为 JPEG，限制最长边和质量，降低后端解析失败概率
  const compressImageFile = async (
    original: File,
    options: { maxWidth?: number; maxHeight?: number; quality?: number } = {}
  ): Promise<File> => {
    const { maxWidth = 1280, maxHeight = 1280, quality = 0.8 } = options
    // 读取为 DataURL
    const dataUrl: string = await new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => resolve(String(reader.result))
      reader.onerror = () => reject(new Error('读取图片失败'))
      reader.readAsDataURL(original)
    })

    // 创建图片并绘制到 canvas
    const img = await new Promise<HTMLImageElement>((resolve, reject) => {
      const image = new Image()
      image.onload = () => resolve(image)
      image.onerror = () => reject(new Error('图片解码失败'))
      image.src = dataUrl
    })

    let { width, height } = img
    const ratio = Math.min(1, maxWidth / width, maxHeight / height)
    width = Math.max(1, Math.round(width * ratio))
    height = Math.max(1, Math.round(height * ratio))

    const canvas = document.createElement('canvas')
    canvas.width = width
    canvas.height = height
    const ctx = canvas.getContext('2d')
    if (!ctx) return original
    ctx.drawImage(img, 0, 0, width, height)

    const blob: Blob | null = await new Promise((resolve) => canvas.toBlob(resolve, 'image/jpeg', quality))
    if (!blob) return original

    // 生成新文件名，统一 jpg 后缀
    const baseName = (original.name || 'image').replace(/\.[^.]+$/, '')
    const compressedFile = new File([blob], `${baseName}.jpg`, { type: 'image/jpeg' })
    return compressedFile
  }

  useEffect(() => {
    request.get('/health/share/knowledgeBase/v1/findDepartment').then(res => {
      if (res.status === 200 && res.data.status === '0000') {
        setDeptOptions((res.data.result || []).map((i: RawDepartment) => ({ label: i.departmentName, value: i.id })))
      }
    })
  }, [])

  const fetchDiseases = (departmentId: number) => {
    request.get('/health/share/knowledgeBase/v1/findDiseaseCategory', { params: { departmentId } }).then(res => {
      if (res.status === 200 && res.data.status === '0000') {
        setDiseaseOptions((res.data.result || []).map((i: RawDisease) => ({ label: i.name, value: i.name })))
      } else {
        setDiseaseOptions([])
      }
    })
  }

  const onSubmit = async (values: Record<string, unknown>) => {
    const { title, departmentId, disease, detail, treatmentHospital,treatmentStartTime, treatmentEndTime, treatmentProcess, amount } = values
    if (!title || !departmentId || !disease || !detail) {
      Toast.show({ content: '请完善必填项' })
      return
    }
    setLoading(true)
    request.post('/health/user/sickCircle/verify/v1/publishSickCircle', {
      title,
      departmentId,
      disease,
      detail,
      treatmentHospital: treatmentHospital || '',
      treatmentStartTime: formatDate(treatmentStartTime as Date | undefined),
      treatmentEndTime: formatDate(treatmentEndTime as Date | undefined),
      treatmentProcess: treatmentProcess || '',
      amount: Number(amount) || 0
    }, {
      headers: { 'Content-Type': 'application/json;charset=UTF-8' }
    }).then(res => {
      if (res.status === 200 && res.data.status === '0000') {
        const newId = res.data.result
        // 如果选择了图片，先上传图片，再跳转
        if (images && images.length > 0 && newId) {
          setUploading(true)
          ;(async () => {
            try {
              // 按顺序逐张上传，避免单次请求过大
              for (const img of images) {
                const raw = img.url ? fileMap[img.url] : undefined
                if (!raw) continue
                const fileToSend = await compressImageFile(raw)
                const fd = new FormData()
                fd.append('sickCircleId', String(newId))
                fd.append('picture', fileToSend, fileToSend.name)
                const uploadRes = await request.post('/health/user/sickCircle/verify/v1/uploadSickCirclePicture', fd)
                if (!(uploadRes.status === 200 && uploadRes.data?.status === '0000')) {
                  throw new Error(uploadRes.data?.message || '图片上传失败')
                }
              }
              Toast.show({ content: '发布并上传图片成功' })
            } catch (err) {
              Toast.show({ content: (err as Error).message || '发布成功，图片上传异常' })
            } finally {
              setUploading(false)
              navigate('/sick-circle', { replace: true })
            }
          })()
        } else {
          Toast.show({ content: '发布成功' })
          navigate('/sick-circle', { replace: true })
        }
      } else {
        Toast.show({ content: res.data.message || '发布失败' })
      }
    }).catch(() => Toast.show({ content: '网络错误，请稍后重试' }))
      .finally(() => setLoading(false))
  }

  return (
    <PermissionGuard operation={PERMISSION_OPERATIONS.PUBLISH}>
      <div className='publish-container'>
        <NavBar onBack={() => navigate(-1)}>发布病友圈</NavBar>
      <Form
        form={form}
        layout='horizontal'
        footer={<Button block color='primary' loading={loading || uploading} type='submit'>发布</Button>}
        onFinish={(values) => {
          const depId = Array.isArray(values.departmentId) ? values.departmentId[0] : values.departmentId
          const diseaseVal = Array.isArray(values.disease) ? values.disease[0] : values.disease
          onSubmit({ ...values, departmentId: depId, disease: diseaseVal })
        }}
      >
        <Form.Item name='title' label='标题' rules={[{ required: true, message: '请输入标题' }]}> 
          <Input maxLength={20} placeholder='请输入标题（最多20字）' />
        </Form.Item>

        <Form.Item
          name='departmentId'
          label='就诊科室'
          rules={[{ required: true, message: '请选择科室' }]}
          trigger='onConfirm'
          onClick={(_e, ref) => openPicker(ref as unknown as MutableRefObject<{ open?: () => void } | null>)}
        >
          <Picker
            columns={[deptOptions]}
            onConfirm={(v) => {
              const depId = v[0] as number
              // 重置主要病症
              form.setFieldsValue({ disease: undefined })
              setDiseaseOptions([])
              if (depId) fetchDiseases(depId)
            }}
          >
            {(items) => {
              const first = (items && items.length ? items[0] : null) as unknown as { label?: unknown } | null
              return typeof first?.label === 'string' ? (first.label as string) : '请选择就诊科室'
            }}
          </Picker>
        </Form.Item>

        <Form.Item
          name='disease'
          label='主要病症'
          rules={[{ required: true, message: '请选择病症' }]}
          trigger='onConfirm'
          onClick={(_e, ref) => openPicker(ref as unknown as MutableRefObject<{ open?: () => void } | null>)}
        >
          <Picker columns={[diseaseOptions]}>
            {(items) => {
              const first = (items && items.length ? items[0] : null) as unknown as { label?: unknown } | null
              return typeof first?.label === 'string' ? (first.label as string) : '请选择主要病症'
            }}
          </Picker>
        </Form.Item>

        <Form.Item name='detail' label='病症详情' rules={[{ required: true, message: '请输入病症详情' }]}>
          <TextArea rows={5} maxLength={300} placeholder='不超过300字' />
        </Form.Item>

        <Form.Header>最近一次治疗经历</Form.Header>
        <Form.Item name='treatmentHospital' label='医院名称'>
          <Input placeholder='请输入医院名称' />
        </Form.Item>
        <Form.Item name='treatmentStartTime' label='开始时间'>
          <DatePicker>
            {(v) => (v ? formatDate(v as Date) : '请选择开始时间')}
          </DatePicker>
        </Form.Item>
        <Form.Item name='treatmentEndTime' label='结束时间'>
          <DatePicker>
            {(v) => (v ? formatDate(v as Date) : '请选择结束时间')}
          </DatePicker>
        </Form.Item>
        <Form.Item name='treatmentProcess' label='治疗过程'>
          <TextArea rows={3} placeholder='治疗过程描述（可选）' />
        </Form.Item>
        <Form.Item name='amount' label='悬赏H币'>
          <Input type='number' placeholder='不填或0表示无悬赏' />
        </Form.Item>

        {/* 图片上传区域 */}
        <Form.Header>最多可添加6张图片</Form.Header>
        <div className='publish-uploader'>
          <ImageUploader
            value={images}
            onChange={(newItems) => {
              setImages(newItems)
              // 同步清理已删除图片的文件映射
              const urls = new Set(newItems.map(i => i.url).filter(Boolean) as string[])
              setFileMap(prev => {
                const next: Record<string, File> = {}
                Object.keys(prev).forEach((k) => { if (urls.has(k)) next[k] = prev[k] })
                return next
              })
            }}
            multiple
            maxCount={6}
            upload={async (file) => {
              // 本地预览：转成 dataUrl 返回，不在此处上传服务器
              const dataUrl = await new Promise<string>((resolve) => {
                const reader = new FileReader()
                reader.onload = () => resolve(String(reader.result))
                reader.readAsDataURL(file)
              })
              setFileMap(prev => ({ ...prev, [dataUrl]: file }))
              return { url: dataUrl }
            }}
          />
          <div className='uploader-tip'>长按图片可排序；发布后自动上传</div>
        </div>
      </Form>
      </div>
    </PermissionGuard>
  )
}
